import {
	Utils
} from "../utils/utils.js";
import {
	DEFAULT_CONFIG,
	HTTP_PARAMS
} from "./const.js";
import {
	isNeedDebounce
} from "./debounce.js";
import {
	Msg
} from "../msg/msg.js";
import {
	Storage
} from "../storage/storage.js";


/** 网络请求 */
export class HttpClient {
	/** 初始化配置 */
	config = null;
	/** 请求参数 */
	params = null;

	/** 初始化 */
	constructor(config) {
		this.config = {
			...Utils.clone(DEFAULT_CONFIG),
			...config,
		};
	}

	/** 发出请求 
	 * @example
	 *  const http = new HttpClient({
			base: 'https://e.aidingyi.cn/',
			setHeader: () => {
				return {
					'Api-Authorize-Token': uni.getStorageSync('token') || ''
				};
			},
		});
		const res: any = await http.request({
			title: `请求列表`,
			uri: `module_listing`,
			method: 'POST',
			data: { module, ...param },
			debounce: 0,
		});

		@returns {Promise<any>}
	*/
	request = async (params) => {
		/** 默认赋值 */
		this.params = {
			...HTTP_PARAMS,
			...params
		};
		/** 请求头部 */
		let header = this.config.setHeader();
		if(this.params.header){
			header = this.params.header;
		}
		/** 请求方式 */
		this.params.method = (this.params.method + '').toUpperCase();
		/** 请求地址 */
		let url = '';
		/** 是否为开发环境 */
		const isDevEnv = process.env.NODE_ENV === 'development';
		if (isDevEnv && this.params.isMock) {
			let mockUrl = '';
			if (this.params.mockUrl) {
				mockUrl = this.params.mockUrl;
			} else {
				mockUrl = `${this.config.mockBase}${this.params.mockUri}`
			}
			url = mockUrl;
		} else {
			if (this.params.uri) {
				url = `${this.config.base}${this.params.uri}`;
			}
			if (this.params.url) {
				url = `${this.params.url}`;
			}
		}



		/** 请求数据 */
		let data = '';
		if (this.params.method === 'POST') {
			// data = JSON.stringify(this.params.data);
			// data = Utils.param(params.data!);
			data = Utils.clone(params.data);
		}
		// 获取url中参数
		let urlParams = Utils.getStrParam(url);
		// 将get参数转换为字符串
		const strGetParams = Utils.param({...urlParams, ...this.params.params});
		// 不含参数的url
		url = url.replace(/\?.*$/, '');
		// 拼接包含参数的url
		if(strGetParams){
			url = `${url}?${strGetParams}`;
		}

		/** 防抖 */
		const isStop = this.params.isDebounce && isNeedDebounce(this.params.cacheKey || this.params.title ||
			'');
		if (isStop) {
			console.log(`[${this.params.title}]请求过于频繁，阻止请求发送。`);
			Msg.hideLoading();
			return Promise.resolve(this.params.dafaultResponse);
		}

		/** 缓存 key */
		const cacheKey = this.params.cacheKey || url;
		/** 缓存数据提取 */
		if (this.params.isCachable) {
			const cacheData = Storage.get(cacheKey);
			if (cacheData !== null) {
				Msg.hideLoading();
				return Promise.resolve(cacheData);
			}
		}
		
		return new Promise((resolve, _reject) => {
			uni.request({
				url,
				method: this.params.method,
				header,
				data: data,
				timeout: this.params.timeout,
				responseType: this.params.responseType,
				withCredentials: this.config.withCredentials,
				success: async (res) => {
					const afterRes = this.config.afterFn(res.data);
					// if (afterRes !== null && afterRes !== undefined) {
					// 	resolve(afterRes);
					// }
					/** 缓存存储 */
					if (this.params.isCachable) {
						Storage.set(cacheKey, res.data);
					}
					resolve(res.data);
				},
				fail: (err) => {
					console.log(`${this.params.title} 请求报错:`);
					console.log(err);
					console.log(this.params);
					// TODO: 这里要做错误处理
					const responseData = err;
					resolve(responseData.errMsg);

				},
				complete: (_res) => {}
			});
		});
	};
}